package com.dongzili.query.common.base;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dongzili.query.common.config.mybatisplus.MybatisPlusUtil;

import com.dongzili.query.common.utils.ReflectUtils;
import com.dongzili.query.common.vo.InsertDataRequest;

import java.io.Serializable;
import java.util.List;


public class BaseServiceUtils<T> {

    private final Class<T> tClass;

    public BaseServiceUtils(Class<T> clazz){
        this.tClass = clazz;
    }

    /**
     * 分页查询
     * @param page
     * @param queryWrapper
     * @return
     */
    public Page<T> selectPage(Page<T> page, QueryWrapper<T> queryWrapper) {
        return MybatisPlusUtil.getMapper(tClass).selectPage(page, queryWrapper);
    }

    /**
     * 根据id查询
     * @param id
     * @return
     */
    public T selectById(Serializable id) {
        return MybatisPlusUtil.getMapper(tClass).selectById(id);
    }

    public Page<T> page(Page<T> page, QueryWrapper<T> queryWrapper) {
        return MybatisPlusUtil.getMapper(tClass).selectPage(page, queryWrapper);
    }


    /**
     * 新增
     * @param request
     * @return
     */
    public T insert(InsertDataRequest<T> request) {
        T data = request.getData();
        if (data == null){
            throw new RuntimeException("新增数据不可为空");
        }
        Class<T> clazz = tClass;

        List<String> names = request.getFields();
        if(names.isEmpty()){
            if(ReflectUtils.hasIdValue(data)){
                MybatisPlusUtil.getMapper(clazz).updateById(data);
            }else{
                MybatisPlusUtil.getMapper(clazz).insert(data);
            }
            return data;
        }else{
            List<String> noExists = ReflectUtils.getNotExistsFields(names, clazz);
            if(!noExists.isEmpty()){
                throw new RuntimeException("数据字段不存在:"+ JSONUtil.toJsonStr(noExists));
            }
        }

        T queryData = ReflectUtils.copyKeyFields(data, names, clazz);
        LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<>(queryData);
        T entity = MybatisPlusUtil.getMapper(clazz).selectOne(wrapper, false);
        if (entity != null){
            if(request.isUpdated()){
                ReflectUtils.copyIdField(entity, data, clazz);
                MybatisPlusUtil.getMapper(clazz).updateById(data);
            }else{
                throw new RuntimeException("数据已存在");
            }
        }else{
            MybatisPlusUtil.getMapper(clazz).insert(data);
        }
        return data;
    }

    /**
     * 根据id更新
     * @param data
     * @return
     * @throws Exception
     */
    public T updateById(T data){

        if(!ReflectUtils.hasIdValue(data)){
            throw new RuntimeException("数据ID不可为空");
        }
        MybatisPlusUtil.getMapper(tClass).updateById(data);
        return data;
    }

    public boolean deleteById(Long id) {
        return MybatisPlusUtil.getMapper(tClass).deleteById(id) > 0;
    }
}
